﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.IO;
using System.Xml;
using System.ServiceModel.Syndication;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.Collections;
using OnlineVideos.Entities;
using OnlineVideos.Data;
using System.Xml.Linq;
using Common.Library;
using System.Reflection;
using InsertIntoDataBase;
using HtmlAgilityPack;
using System.Collections.ObjectModel;
using System.IO.IsolatedStorage;
using OnlineVideos.ViewModels;
using MarkHeath.StarRating;

using OnlineVideos.Views;
using System.ComponentModel;
using System.Threading;
using System.Windows.Input;

namespace Social_Celebrities
{
    public class Extraparam
    {
        public string Title
        {
            get;
            set;
        }
      
        public string ImageUrl
        {
            get;
            set;
        }
        public Visibility Control
        {
            get;
            set;
        }
        public int Id
        {
            get;
            set;
        }
    }
    public class DownloadBlogInfo
    {

        public CastProfile cast
        {
            get;
            set;
        }
        public List<Phone_SocialFeed> feeds
        {
            get;
            set;
        }
        public Extraparam extra
        {
            get;
            set;
        }
        
        
       
    }
    public partial class OnlineShare : PhoneApplicationPage
    {
        double oldrate = 0;
        int count = 10;
        int BindId = 0;
        double Rate = 5.0;
        public bool sortDate = false;
        bool sortByRating = false;
        public AutoResetEvent auto = new AutoResetEvent(false);
        public AutoResetEvent auto1 = new AutoResetEvent(false);
        Dictionary<string, object> dic1 = default(Dictionary<string, object>);
        public List<Dictionary<string, object>> RatingDetails = new List<Dictionary<string, object>>();
        public ObservableCollection<DownloadBlogInfo> DownloadList = default(ObservableCollection<DownloadBlogInfo>);
        public int startIndex = 1;
        public int maxresults = 10;
        public List<int> ListId = new List<int>();
        public OnlineShare()
        {
            InitializeComponent();
            Loaded += OnlineShare_Loaded;
        }

        void OnlineShare_Loaded(object sender, RoutedEventArgs e)
        {
         
            OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
          
            TbSearch.Text = string.Empty;
            sortDate = false;
            sortByRating = false;
            DownloadList = new ObservableCollection<DownloadBlogInfo>();
            OnlineList.ItemsSource = DownloadList;
           
            startIndex = 1;
            maxresults = 10;

                BlogCategoryTable bt = context.BlogCategory.FirstOrDefault();
                if (bt != null)
                {
                    loaddata(bt.BlogUrl + "start-index=" + startIndex + "&max-results=" + maxresults + "&alt=rss");
                }
        }
        public void loaddata(string url)
        {
            try
            {
                string feed = string.Empty;
                WebClient wclient = new WebClient();
                wclient.OpenReadCompleted += (sender1, e1) =>
                {
                    if (e1.Error != null)
                        return;
                   double Rating=default(double);
                   Stream str = e1.Result;
                   XmlReader response = XmlReader.Create(str);
                   SyndicationFeed feeds = SyndicationFeed.Load(response);
                   string[] stringSeparators = new string[] { "??" };
                   if (feeds.Items.Count() > 0)
                   {
                        foreach (SyndicationItem f in feeds.Items)
                        {
                            bool exists = false;
                            foreach (SyndicationCategory sc in f.Categories)
                            {
                                if (sc.Name == "hide")
                                {
                                    exists = true;
                                }
                                else if (sc.Name != f.Title.Text)
                                {
                                 try
                                    {
                                        Rating= Convert.ToDouble(sc.Name);
                                    }
                                 catch
                                      {
                                    
                                      }
                                 }
                             }
                            if (exists == false)
                            {

                                Dictionary<string, object> BlogDic = new Dictionary<string, object>();
                                string[] xml = new string[2];
                                DownloadBlogInfo db = new DownloadBlogInfo();
                                db.extra = new Extraparam();
                                feed = HttpUtility.HtmlDecode(Regex.Replace(f.Summary.Text, "<[^>]+?>", ""));
                                HtmlDocument doc = new HtmlDocument();
                                doc.LoadHtml(f.Summary.Text);
                                foreach (HtmlNode node in doc.DocumentNode.SelectNodes(" //img"))
                                {
                                    if (node.OuterHtml.Contains("src"))
                                    {
                                        db.extra.ImageUrl = node.Attributes["src"].Value;
                                    }
                                }
                                
                                    xml[0] = feed.Split(stringSeparators, StringSplitOptions.None)[0];
                                
                                    xml[1] = feed.Substring(xml[0].ToString().Length+2);
                                
                                 BindId++;
                                 db.extra.Id = BindId;
                                 BlogDic.Add("ID",BindId);
                                 BlogDic.Add("PostID",f.Id);
                                 BlogDic.Add("Title", xml[0].ToString());
                                 BlogDic.Add("XML", xml[1].ToString());
                                 BlogDic.Add("Image", db.extra.ImageUrl);
                                 BlogDic.Add("Rating", Rating);
                               
                                TextReader read = new StringReader(xml[1].ToString());
                                XDocument xdoc = XDocument.Load(read);
                                OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
                                var TablesList = context.UserTable.OrderBy(i => i.TableOrder).GroupBy(i => i.TableName).ToList();

                                foreach (var TableName in TablesList)
                                {
                                    Assembly DataAssembly = Assembly.Load(Constants.NamespaceForData);
                                    Type TableType = DataAssembly.GetType(Constants.NamespaceForData + "." + TableName.Key.ToString());
                                    object TableInstance = Activator.CreateInstance(TableType);
                                    Convert.ChangeType(TableInstance, TableType, null);
                                    var InsertType = typeof(InsertData<>);
                                    Type[] Typeargs = { TableType };
                                    var makeme = InsertType.MakeGenericType(Typeargs);
                                    object InsertInstance = Activator.CreateInstance(makeme);
                                    var Param = xdoc.Descendants("NewDataSet").Elements().Where(i => i.Name == TableName.Key.ToString());

                                    if (Param != null)
                                    {
                                        if (TableName.Key.ToString()=="Phone_SocialFeed")
                                        {
                                            string propertyname = string.Empty;
                                            List<Phone_SocialFeed> FeedList = new List<Phone_SocialFeed>();
                                            foreach (var para in Param)
                                            {

                                                PropertyInfo[] ConditionProperty = db.GetType().GetProperties();
                                                foreach (PropertyInfo property in ConditionProperty)
                                                {
                                                    if (property.PropertyType.FullName.Contains(TableType.FullName))
                                                    {
                                                        propertyname = property.Name;
                                                        break;
                                                    }
                                                }

                                                TableInstance = InsertInstance.GetType().GetMethod("XMLToEntity").Invoke(InsertInstance, new object[] { para.ToString() });
                                                FeedList.Add((Phone_SocialFeed)TableInstance);
                                            }
                                            db.GetType().GetProperty(propertyname).SetValue(db, FeedList, null);
                                        }
                                        else
                                        {
                                            string propertyname = string.Empty;
                                            PropertyInfo[] ConditionProperty = db.GetType().GetProperties();
                                            foreach (PropertyInfo property in ConditionProperty)
                                            {
                                                if (property.PropertyType == TableType)
                                                {
                                                    propertyname = property.Name;
                                                    break;
                                                }
                                            }

                                            TableInstance = InsertInstance.GetType().GetMethod("XMLToEntity").Invoke(InsertInstance, new object[] { Param.FirstOrDefault().ToString() });
                                            db.GetType().GetProperty(propertyname).SetValue(db, TableInstance, null);
                                        }
                                    }
                                }
                                db.extra.Control = Visibility.Visible;
                                db.extra.Title = db.cast.Name;
                                Dispatcher.BeginInvoke(() =>
                                {
                                    DownloadList.Add(db);
                                });
                                RatingDetails.Add(BlogDic);
                            }
                            str.Close();
                        }
                       
                        if (((double)DownloadList.Count()) / 10 % 1 == 0)
                        {
                              Dispatcher.BeginInvoke(() =>
                                {
                            notavailable.Visibility = Visibility.Collapsed;
                                });
                            DownloadBlogInfo db1 = new DownloadBlogInfo();
                            db1.extra = new Extraparam();
                            db1.extra.Title = "get more..";
                            db1.extra.Control = Visibility.Collapsed;
                             Dispatcher.BeginInvoke(() =>
                                {
                            DownloadList.Add(db1);
                                });
                        }
                        else if (!(((double)DownloadList.Count()) / 10 % 1 == 0))
                        {
                            if (sortByRating == false)
                            {
                                DownloadBlogInfo db1 = new DownloadBlogInfo();
                                db1.extra = new Extraparam();
                                db1.extra.Title = "";
                                db1.extra.Control = Visibility.Collapsed;
                                Dispatcher.BeginInvoke(() =>
                                   {
                                       DownloadList.Add(db1);
                                   });
                            }
                        }
                        else if (DownloadList.Count() == 0)
                        {
                            Dispatcher.BeginInvoke(() =>
                            {
                                notavailable.Visibility = Visibility.Visible;
                            });
                        }
                    }
                    else
                    {
                        if (DownloadList.Count == 0)
                        {
                            Dispatcher.BeginInvoke(() =>
                            {
                                notavailable.Visibility = Visibility.Visible;
                            });
                        }
                        foreach (DownloadBlogInfo db in DownloadList)
                        {
                            if (db.extra.Title == "get more..")
                            {
                                Dispatcher.BeginInvoke(() =>
                                {
                                DownloadList.Remove(db);
                                });
                            }
                        }
                    }
                    if (sortByRating == true)
                        auto1.Set();
                };

                wclient.OpenReadAsync(new Uri(url, UriKind.RelativeOrAbsolute));
                if (sortByRating == true)
                    auto1.WaitOne();
            }
            catch (Exception ex)
            {
                if (sortByRating == true)
                    auto1.Set();
                string msg = ex.Message;
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
                if (!string.IsNullOrEmpty(TbSearch.Text))
                {
                    BindId = 0;
                    RatingDetails.Clear();
                    startIndex = 1;
                    maxresults = 10;
                    sortDate = false;
                    sortByRating = false;
                    DownloadList.Clear();
                    OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
                    BlogCategoryTable bt = context.BlogCategory.FirstOrDefault();
                     string SearchQuery=string.Empty;
                     foreach (string ss in TbSearch.Text.ToString().Split(' '))
                     {
                         if (string.IsNullOrEmpty(SearchQuery))
                         SearchQuery =ss.Substring(0,1).ToUpper()+ss.Substring(1).ToLower();
                         else
                             SearchQuery = SearchQuery + " " + ss.Substring(0, 1).ToUpper() + ss.Substring(1).ToLower();
                     }

                     loaddata(bt.BlogUrl + "start-index=" + startIndex + "&max-results=" + maxresults + "&category=" + SearchQuery + "&alt=rss");
                }
          
            //http://www.blogger.com/feeds/blogID/posts/default?updated-min=2008-03-16T00:00:00&updated-max=2008-03-24T23:59:59&orderby=updated
        }

        private void sort_Click_1(object sender, EventArgs e)
        {
            BindId = 0;
            RatingDetails.Clear();
            startIndex = 1;
            maxresults = 10;
            sortDate = true;
            sortByRating = false;
            DownloadList.Clear();
            TbSearch.Text = string.Empty;
            OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
            BlogCategoryTable bt = context.BlogCategory.FirstOrDefault();
            loaddata(bt.BlogUrl + "start-index=" + startIndex + "&max-results=" + maxresults + "&orderby=updated&alt=rss");
        }

        private void ApplicationBarIconButton_Click_1(object sender, EventArgs e)
        {
            foreach (int id in ListId)
            {
                DownloadBlogInfo di = OnlineList.ItemsSource.Cast<DownloadBlogInfo>().Where(i => i.extra.Id == id).FirstOrDefault();
                SaveToDatabase(di);
            }
             NavigationService.GoBack();
        }

        private void SaveToDatabase(DownloadBlogInfo di)
        {
            PropertyInfo[] ConditionProperty = di.GetType().GetProperties();
            foreach (PropertyInfo property in ConditionProperty)
            {
                Assembly DataAssembly = Assembly.Load(Constants.NamespaceForData);
                if (property.PropertyType.Name.Contains("List"))
                {
                    Type TableType = DataAssembly.GetType(Constants.NamespaceForData + ".Phone_SocialFeed");
                    if (TableType != null)
                    {
                        object TableInstance = Activator.CreateInstance(TableType);

                        if (di.GetType().GetProperty(property.Name.ToString()).GetValue(di, null) != null)
                        {
                            foreach (Phone_SocialFeed ps in (List<Phone_SocialFeed>)di.GetType().GetProperty(property.Name.ToString()).GetValue(di, null))
                            {
                                var InsertType = typeof(InsertData<>);
                                Type[] Typeargs = { TableType };
                                var makeme = InsertType.MakeGenericType(Typeargs);
                                object InsertInstance = Activator.CreateInstance(makeme);
                                InsertInstance.GetType().GetProperty("ParameterList").SetValue(InsertInstance, ps, null);
                                InsertInstance.GetType().GetMethod("Insert").Invoke(InsertInstance, null);
                            }
                        }
                    }
                }
                else
                {
                    Type TableType = DataAssembly.GetType(Constants.NamespaceForData + "." + property.PropertyType.Name.ToString());
                    if (TableType != null)
                    {
                        object TableInstance = Activator.CreateInstance(TableType);

                        if (di.GetType().GetProperty(property.Name.ToString()).GetValue(di, null) != null)
                        {
                            var InsertType = typeof(InsertData<>);
                            Type[] Typeargs = { TableType };
                            var makeme = InsertType.MakeGenericType(Typeargs);
                            object InsertInstance = Activator.CreateInstance(makeme);
                            InsertInstance.GetType().GetProperty("ParameterList").SetValue(InsertInstance, di.GetType().GetProperty(property.Name.ToString()).GetValue(di, null), null);
                            InsertInstance.GetType().GetMethod("Insert").Invoke(InsertInstance, null);
                        }
                    }
                }
            }
        }

        private void CheckBox_Checked_1(object sender, RoutedEventArgs e)
        {
            if (!ListId.Contains((int)(sender as CheckBox).Tag))
                ListId.Add((int)(sender as CheckBox).Tag);
        }

        private void CheckBox_Unchecked_1(object sender, RoutedEventArgs e)
        {
            if (ListId.Contains((int)(sender as CheckBox).Tag))
                ListId.Remove((int)(sender as CheckBox).Tag);
        }
       
        private void Tbtitle_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
        {
            if ((sender as TextBlock).Text == "get more..")
            {
                foreach (DownloadBlogInfo db in DownloadList.ToList())
                {
                    if (db.extra.Title == "get more..")
                    {
                        DownloadList.Remove(db);
                    }
                }

                startIndex = count + 1;
                count = startIndex + 9;
                maxresults = 10;
                if (!string.IsNullOrEmpty(TbSearch.Text))
                {
                    OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
                    BlogCategoryTable bt = context.BlogCategory.FirstOrDefault();
                    loaddata(bt.BlogUrl + "start-index=" + startIndex + "&max-results=" + maxresults + "&category=" + TbSearch.Text + "&alt=rss");
                }
                else if (sortDate == true)
                {
                    OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
                    BlogCategoryTable bt = context.BlogCategory.FirstOrDefault();
                    loaddata(bt.BlogUrl + "start-index=" + startIndex + "&max-results=" + maxresults + "&orderby=updated&alt=rss");
                }
                else if (sortByRating == true)
                {
                    int ratecnt=0;
                    foreach(Dictionary<string,object> d in RatingDetails)
                    {
                        foreach(KeyValuePair<string,object> k in d)
                        {
                            if(k.Value.ToString()==Rate.ToString())
                            {
                                ratecnt++;
                            }
                        }
                    }
                    if (oldrate == 0)
                    {
                        oldrate = Rate;
                    }
                    startIndex = ratecnt == 0 ? 1 : ratecnt;
                    count = startIndex + 9;
                    maxresults = 10;
                    GetByRating(startIndex, maxresults);
                }
                else
                {
                    OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
                    BlogCategoryTable bt = context.BlogCategory.FirstOrDefault();
                    loaddata(bt.BlogUrl + "start-index=" + startIndex + "&max-results=" + maxresults + "&alt=rss");
                }
            }
        }

        private void TextBlock_Loaded_1(object sender, RoutedEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            if (tb.Text == "Select Category")
            {
                tb.Visibility = Visibility.Collapsed;
                tb.Loaded -= TextBlock_Loaded_1;
            }
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            dic1 = new Dictionary<string,object>();
          MenuItem menu=sender as MenuItem;
          int selectedId = (int)menu.Tag;
          foreach (Dictionary<string, object> dic in RatingDetails)
          {
              foreach (KeyValuePair<string, object> k in dic.Where(i => i.Key == "ID"))
              {
                  if (k.Value.ToString() == selectedId.ToString())
                  {
                      dic1 = dic;
                  }
              }
              if (dic1.Count > 0)
                  break;
          }
    
            StarRatingControl starratingcontrol = new StarRatingControl();
            var ss = dic1.Where(i => i.Key == "Rating").FirstOrDefault().Value;
            starratingcontrol.Rating =Convert.ToInt32(Convert.ToDouble(dic1.Where(i=>i.Key=="Rating").FirstOrDefault().Value.ToString()));
            RateThisCelebrity(starratingcontrol, dic1);

        }
        public void RateThisCelebrity(StarRatingControl starRating, Dictionary<string, object> dic)
        {
            RatingPopup ratingPopup=new RatingPopup();
            ratingPopup.showPopup(starRating.Rating, "onlineshare", dic);
        }

        private void PhoneApplicationPage_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (Convert.ToBoolean(e.NewValue))
            {
                UpdateRatingInBlog u = new UpdateRatingInBlog();
                BackgroundWorker bg = new BackgroundWorker();
                bg.DoWork += bg_DoWork;
                bg.RunWorkerCompleted += bg_RunWorkerCompleted;
                bg.RunWorkerAsync(u);
            }
        }

        void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            
        }

        void bg_DoWork(object sender, DoWorkEventArgs e)
        {
            if (string.IsNullOrEmpty(AppSettings.BloggerAccessTokenForRating))
            {
                UpdateRatingInBlog u = (UpdateRatingInBlog)e.Argument;
                u.Login("socialcelebrities@gmail.com", "lartsocialcelebrities", "Rating");
                u.UploadItem(auto, dic1);
                auto.WaitOne();
            }
            else
            {
                UpdateRatingInBlog u = (UpdateRatingInBlog)e.Argument;
                u.UploadItem(auto, dic1);
                auto.WaitOne();
            }
        }

        private void sort1_Click(object sender, EventArgs e)
        {
            sortByRating = true;
            Rate = 5;
            BindId = 0;
            RatingDetails.Clear();
            startIndex = 1;
            maxresults = 10;
            sortDate = false;
            DownloadList.Clear();
            GetByRating(startIndex,maxresults);
        }
        private void GetByRating(int start,int cnt)
        {
               
                BackgroundWorker bgw = new BackgroundWorker();
                bgw.DoWork += bgw_DoWork;
                bgw.RunWorkerCompleted += bgw_RunWorkerCompleted;
                object[] str = new object[3];
                str[0] = start.ToString();
                str[1] = cnt.ToString();
                str[2] =Rate;
                bgw.RunWorkerAsync(str);
               
        }
        
        void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            if (((double)DownloadList.Count()) / 10 % 1 != 0 && Rate > 1)
            {
                Rate = Rate - 1;
                startIndex = 1;
                count = 10 - DownloadList.Count;
                maxresults = 10 - DownloadList.Count;
                GetByRating(startIndex, maxresults);
            }
            if (((double)DownloadList.Count()) / 10 % 1 == 0 && Rate > 1 && oldrate!=0)
            {
                Rate = Rate - 1;
                startIndex = 1;
                count = startIndex + 9;
                maxresults = 10;
                GetByRating(startIndex, maxresults);
                oldrate = 0;
            }
           
           
        }

        void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] str = new object[3];
            str = (object[])e.Argument;
            OnlineVideoDataContext context = new OnlineVideoDataContext(Constants.DatabaseConnectionString);
            BlogCategoryTable bt = context.BlogCategory.FirstOrDefault();
            loaddata(bt.BlogUrl + "start-index=" + str[0].ToString() + "&max-results=" + str[1].ToString() + "&category=" + Convert.ToDouble(str[2]) + "&alt=rss");
            
        }

        private void TbSearch_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                Button_Click_1(null, null);
            }
        }
    }
}